package com.dhy.qigsaw.splash

import android.app.Activity
import android.content.Context
import com.dhy.qigsaw.splash.ApiUtil.AppConfig
import com.dhy.qigsaw.splash.data.*
import com.dhy.versionchecker.IVersion
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.ResponseBody
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
import java.util.*

object ApiUtil {
    val AppConfig: AppConfigService by lazy {
        ServiceLoader.load(AppConfigService::class.java).first()
    }
    private const val QIGSAW_URL_HEAD = "http://www.qigsaw.com/"
    private fun Request.fixUrl(): Request {
        val url = url.toString()
        return if (url.startsWith(QIGSAW_URL_HEAD)) {
            newBuilder().url(url.replace(QIGSAW_URL_HEAD, AppConfig.apkFileHost)).build()
        } else this
    }

    private val httpClient: OkHttpClient by lazy {
        OkHttpClient.Builder()
            .addInterceptor {
                val request = it.request().fixUrl()
                println("ApiUtil ${request.url}")
                it.proceed(request)
            }.build()
    }
    private val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
            .baseUrl(AppConfig.apkFileHost.fixedBaseUrlTail())
            .client(httpClient)
            .build()
    }
    val api: Api by lazy {
        retrofit.create(Api::class.java)
    }

    fun checkSplitUpdate(activity: Activity, onResponse: (AppVersion?) -> Unit) {
        checkUpdate(activity, AppConfig.APPLICATION_ID + "-split", AppConfig.VERSION_TYPE.toInt(), onResponse)
    }

    private fun checkUpdate(activity: Activity, packageName: String, versionType: Int, onResponse: (AppVersionExt?) -> Unit) {
        api.checkVersion(packageName, versionType)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                if (!activity.isFinishing) onResponse(it.data)
            }, {
                it.printStackTrace()
                if (!activity.isFinishing) onResponse(null)
            })
    }

    /**
     *  http://192.168.50.58//test.apk ->http://192.168.50.58/test.apk
     *  file:///root//test.apk ->file:///root/test.apk, file('/root/test.apk')
     * */
    private fun String.fixDoubleSeparatorError(): String {
        return replace("([^:/])/{2,}".toRegex(), "$1/")
    }

    private fun String.fixedBaseUrlTail(): String {
        return if (this.endsWith('/')) this else "$this/"
    }
}

interface Api {
    /**
     * 检查更新
     * */
    @GET("admin/versioninfo/get")
    fun checkVersion(@Query("packagename") packageName: String, @Query("versiontype") versionType: Int): Observable<ResponseW<AppVersionExt?>>

    @GET
    fun download(@Url url: String): Observable<ResponseBody>

    @POST("https://api.leancloud.cn/1.1/classes/TestResult")
    fun postLeanCloudTestResult(@Header("X-LC-Id") lcId: String, @Header("X-LC-Key") lcKey: String, @Body result: TestResult): Observable<ResponseBody>
}

fun Api.checkAppVersion(): Observable<IVersion> {
    return checkVersion(AppConfig.APPLICATION_ID, AppConfig.VERSION_TYPE.toInt()).map { it?.data ?: AppVersionExt() }
}

fun Api.checkSplitVersion(): Observable<IVersion> {
    return checkVersion(AppConfig.APPLICATION_ID + "-split", AppConfig.VERSION_TYPE.toInt()).map { it?.data ?: AppVersionExt() }
}

fun Api.postResult(context: Context, result: TestResult): Observable<ResponseBody> {
    val id = context.getString(R.string.X_LC_ID)
    val key = context.getString(R.string.X_LC_KEY)
    return postLeanCloudTestResult(id, key, result)
}